<template>
  <div class="slot-ref-example">
    <h2>router-view ref — 示例</h2>

    <section>
      <h3>错误示例：在 <code>router-view</code> 上使用 <code>ref</code></h3>
      <p>
        如果把 <code>ref</code> 直接挂在 <code>router-view</code> 上，得到的 是
        router-view 的包装实例或 DOM，而不是匹配到的路由组件实例。
      </p>
      <!-- 错误示例：ref 挂在 router-view 上 -->
      <router-view ref="wrongRef" />
      <div class="controls">
        <button @click="showWrongRef">查看 wrongRef</button>
        <span class="result">{{ wrongInspect }}</span>
      </div>
    </section>

    <hr />

    <section>
      <h3>
        正确示例：使用 <code>v-slot</code> + 将 <code>ref</code> 挂在实际组件上
      </h3>
      <p>
        使用
        <code>router-view</code>
        的插槽属性可以取得匹配的组件构造（<code>Component</code>）， 然后通过
        <code>&lt;component :is="Component" ref="..." /&gt;</code> 将
        <code>ref</code>
        绑定到真实的路由组件实例。
      </p>

      <router-view v-slot="{ Component }">
        <!-- 正确示例：ref 挂在实际的路由组件实例 -->
        <component :is="Component" ref="mainContent" />
      </router-view>

      <div class="controls">
        <button @click="callChildMethod">调用 child.showMessage()</button>
        <span class="result">{{ correctInspect }}</span>
      </div>
    </section>
  </div>
</template>

<script setup>
import { ref } from "vue";

// 错误示例的引用（会引用到 router-view 本体）
const wrongRef = ref(null);
// 正确示例中引用到的真实子组件实例
const mainContent = ref(null);

const wrongInspect = ref("");
const correctInspect = ref("");

function showWrongRef() {
  // 简短说明 wrongRef 指向什么
  wrongInspect.value = wrongRef.value
    ? wrongRef.value.$el
      ? "router-view 组件包装器（具有 $el）"
      : String(wrongRef.value)
    : "null";
}

function callChildMethod() {
  // 子组件通过 defineExpose 暴露 showMessage
  if (mainContent.value && mainContent.value.showMessage) {
    try {
      const ret = mainContent.value.showMessage();
      correctInspect.value = "已调用 showMessage()，返回：" + String(ret);
    } catch (e) {
      correctInspect.value = "调用 showMessage 失败：" + e.message;
    }
  } else {
    correctInspect.value = "mainContent 引用不可用或方法缺失";
  }
}
</script>

<style scoped>
.slot-ref-example {
  padding: 16px;
}
.controls {
  margin-top: 8px;
}
.result {
  margin-left: 12px;
  color: #444;
}
hr {
  margin: 18px 0;
}
</style>
